/*
 * permutations.cpp
 *
 *  Created on: May 2, 2011
 *      Author: shai
 */

#include "permutations.h"

double printPermutation(const permutation* p)
{
	for(int i=0 ; i <= p->cycles ; i++)
	{
		std::cout << "[";
		for (int j=0 ; j<p->cycleSize ; j++)
			std::cout << p->indices[p->cycleSize*i+j] << " ";
		std::cout << "]";
	}
	std::cout << std::endl;
	return 1;
}

int find_all_cycles(int n, int c, std::function<double (permutation*)> action)
{
	static permutation *p = NULL;
	bool first = false;
	static int sum = 0;
	static std::vector<int>::iterator begin;
	if (p == NULL)
	{
		p = new permutation(n,c);
		begin = p->indices.begin();
		sum = 0;
		first = true;
	}
	do
	{
		{
			if (p->cycles > 0 && *begin < *(begin-c)) continue; //eliminate redundancy
			if (action != NULL)  sum += action(p);
			else sum++;
			if (n - c*(p->cycles+1) > c) { //add another cycle if there's room
				begin += c;
				p->cycles++;
				find_all_cycles(n, c, action);
				begin -= c;
				p->cycles--;
			}
		} while(next_permutation(begin, begin + c));
	} while(boost::next_combination(begin, begin + c, p->indices.end()));
	if (first)
	{
		delete(p);
		p = NULL;
	}
	return sum;
}
